<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.5"/>
<title>NDK Programmer&#39;s Guide: Prebuilt Libraries</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
  $(window).load(resizeHeight);
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td style="padding-left: 0.5em;">
   <div id="projectname">NDK Programmer&#39;s Guide
   </div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.5 -->
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;"
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('md_3__key__topics__libraries__p_r_e_b_u_i_l_t_s.html','');});
</script>
<div id="doc-content">
<div class="header">
  <div class="headertitle">
<div class="title">Prebuilt Libraries </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>Android NDK r5 introduced support for prebuilt libraries (shared and static), i.e. the ability to include and use, in your applications, prebuilt version of libraries.</p>
<p>This feature can be useful for two things:</p>
<ol type="1">
<li>You want to distribute your own libraries to third-party NDK developers without distributing your sources.</li>
<li>You want to use a prebuilt version of your own libraries to speed up your build.</li>
</ol>
<p>This document explains how this support works.</p>
<h2>Declaring a prebuilt library module</h2>
<p>Each prebuilt library must be declared as a <em>single</em> independent module to the build system. Here is a trivial example where we assume that the file "libfoo.so" is located in the same directory than the Android.mk below: </p>
<pre class="fragment">    LOCAL_PATH := $(call my-dir)

    include $(CLEAR_VARS)
    LOCAL_MODULE := foo-prebuilt
    LOCAL_SRC_FILES := libfoo.so
    include $(PREBUILT_SHARED_LIBRARY)
</pre><p>Notice that, to declare such a module, you really only need the following:</p>
<ol type="1">
<li>Give the module a name (here '<code>foo-prebuilt</code>'). This does not need to correspond to the name of the prebuilt library itself.</li>
<li><p class="startli">Assign to LOCAL_SRC_FILES the path to the prebuilt library you are providing. As usual, the path is relative to your LOCAL_PATH.</p>
<p class="startli">IMPORTANT: You <em>must</em> ensure that the prebuilt library corresponds to the target ABI you are using. More on this later.</p>
</li>
<li>Include PREBUILT_SHARED_LIBRARY, instead of BUILD_SHARED_LIBRARY, if you are providing a shared, library. For static ones, use PREBUILT_STATIC_LIBRARY.</li>
</ol>
<p>A prebuilt module does not build anything. However, a copy of your prebuilt shared library will be copied into $PROJECT/obj/local, and another will be copied and stripped into <code>$PROJECT/libs/&lt;abi&gt;</code>.</p>
<h2>Referencing the prebuilt library in other modules</h2>
<p>Simply list your prebuilt module's name in the LOCAL_STATIC_LIBRARIES or LOCAL_SHARED_LIBRARIES declaration in the Android.mk of any module that depends on them.</p>
<p>For example, a naive example of a module using libfoo.so would be: </p>
<pre class="fragment">    include $(CLEAR_VARS)
    LOCAL_MODULE := foo-user
    LOCAL_SRC_FILES := foo-user.c
    LOCAL_SHARED_LIBRARIES := foo-prebuilt
    include $(BUILD_SHARED_LIBRARY)
</pre><h2>Exporting headers for prebuilt libraries</h2>
<p>The example above was called 'naive' because, in practice, the code in foo-user.c is going to depend on specific declarations that are normally found in a header file distributed with the prebuilt library (e.g. "foo.h").</p>
<p>In other words, foo-user.c is going to have a line like: </p>
<pre class="fragment">  #include &lt;foo.h&gt;
</pre><p>And you need to provide the header and its include path to the compiler when building the foo-user module.</p>
<p>A simple way to deal with that is to use exports in the prebuilt module definition. For example, assuming that a file "foo.h" is located under the 'include' directory relative to the prebuilt module, we can write: </p>
<pre class="fragment">    include $(CLEAR_VARS)
    LOCAL_MODULE := foo-prebuilt
    LOCAL_SRC_FILES := libfoo.so
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
    include $(PREBUILT_SHARED_LIBRARY)
</pre><p>The LOCAL_EXPORT_C_INCLUDES definition here ensures that any module that depends on the prebuilt one will have its LOCAL_C_INCLUDES automatically prepended with the path to the prebuilt's include directory, and will thus be able to find headers inside that.</p>
<h2>Debugging prebuilt binaries</h2>
<p>We recommend you to provide prebuilt shared libraries that contain debug symbols. The version that is installed into <code>$PROJECT/libs/&lt;abi&gt;/</code> is always stripped by the NDK build system, but the debug version will be used for debugging purposes with ndk-gdb.</p>
<h2>ABI Selection of prebuilt binaries</h2>
<p>As said previously, it is crucial to provide a prebuilt shared library that is compatible with the targeted ABI during the build. To do that, check for the value of TARGET_ARCH_ABI, its value will be: </p>
<pre class="fragment">  armeabi     =&gt; when targeting ARMv5TE or higher CPUs
  armeabi-v7a =&gt; when targeting ARMv7 or higher CPUs
  x86         =&gt; when targeting x86 CPUs
  mips        =&gt; when targeting MIPS CPUs
</pre><p>Note that armeabi-v7a systems can run armeabi binaries just fine.</p>
<p>Here's an example where we provide two versions of a prebuilt library and select which one to copy based on the target ABI: </p>
<pre class="fragment">    include $(CLEAR_VARS)
    LOCAL_MODULE := foo-prebuilt
    LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libfoo.so
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
    include $(PREBUILT_SHARED_LIBRARY)
</pre><p>Here. we assume that the prebuilt libraries to copy are under the following directory hierarchy: </p>
<pre class="fragment">    Android.mk            --&gt; the file above
    armeabi/libfoo.so     --&gt; the armeabi prebuilt shared library
    armeabi-v7a/libfoo.so --&gt; the armeabi-v7a prebuilt shared library
    include/foo.h         --&gt; the exported header file
</pre><p>NOTE: Remember that you don't need to provide an armeabi-v7a prebuilt library, since an armeabi one can easily run on the corresponding devices. </p>
</div></div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="footer">Generated on Wed Jun 25 2014 00:51:19 for NDK Programmer&#39;s Guide by
    <a href="http://www.doxygen.org/index.html">
    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.5 </li>
  </ul>
</div>
</body>
</html>
